; Archivo "tstring.asm"
;
; Tabla de string
;
; Manipulacion de una tabla doblemente indexada.
; Se envia a traves del puerto serie las cadenas de la tabla.
;
; Compilar: 'npasm tstring.asm'
;
%include "p16f877a.inc"

; Definiciones necesarias para calcular el valor de SPBRG
%define BAUD    9600
%define Fosc    4000000

; Macro para calcular el valor de SPBRG (asume que BRGH=1)
; (Ver formula para calcular SPBRG en la hoja de datos).
%define VAL_SPBRG ((Fosc - (16 * BAUD)) / (16 * BAUD)) & 0xFF


; Seccion de datos
section data
istr:  resb 1
nstr:  resb 1

; Seccion de codigo
section code
inicio:
	call conf_rs232
	
	mov w, STR_COLOR ; color
	mov [nstr], w
	call enviar_string
	
	mov w, STR_ROJO  ; rojo
	mov [nstr], w
	call enviar_string
	
	mov w, STR_NL    ; salto de linea
	mov [nstr], w
	call enviar_string
	
	mov w, STR_COLOR ; color
	mov [nstr], w
	call enviar_string
	
	mov w, STR_VERDE ; verde
	mov [nstr], w
	call enviar_string
	
	mov w, STR_NL    ; salto de linea
	mov [nstr], w
	call enviar_string
	
	jmp $

; Configuracion del puerto serie
conf_rs232:
	set   [STATUS].RP0    ; banco 1
	mov   w, 0xFF
	mov   [TRISC], w      ; configurar puerto C
	mov   w, VAL_SPBRG
	mov   [SPBRG], w      ; generador de 'baud rate'
	mov   w, (1<<BRGH | 1<<TXEN) & ~(1<<TX9 | 1<<SYNC)
	mov   [TXSTA], w
	clr   [PIE1].TXIE     ; habilitar transmision
	clr   [STATUS].RP0    ; banco 0
	set   [RCSTA].SPEN    ; habilitar puerto serie
	ret
	
; Envia por el puerto serie una cadena de la tabla de string
; Entrada:
;  NSTR = indice de la cadena en la tabla de string
; Salida:
;   - nada -
enviar_string:
	clr   [istr]
bucle:
	mov   w, [istr]
	call  tab_str     ; cargamos el caracter del mensaje a mostrar en W
	add   w, 0
	jz    [STATUS].Z
	ret
	call  enviar_w
	inc   [istr]
	jmp   bucle

; Envia por el puerto serie el caracter en W
; Entrada:
;   W = caracter a enviar por el puerto serie
; Salida:
;   - nada -
enviar_w:
	jnz   [PIR1].TXIF  ; Esperamos que finalice Tx en tramite...
	jmp   enviar_w
	mov   [TXREG], w
	ret

; Manipulacion de la tabla de string (tabla doblemente indexada)
; Entrada:
;   NSTR = indice de la cadena dentro de la tabla
;   ISTR = indice del caracter dentro de la cadena
; Salida:
;   Caracter en la posicion ISTR de la cadena NSTR
align 16
tab_str:
	mov w, [nstr]
	add [pcl], w
	jmp str_0
	jmp str_1
	jmp str_2
	jmp str_3

%define STR_COLOR 0
str_0:
	mov  w, [istr]
	add  [pcl], w
	mkretlw  "Color: ", 0x00

%define STR_ROJO 1
str_1:
	mov  w, [istr]
	add  [pcl], w
	mkretlw  "Rojo", 0x00
	
%define STR_VERDE 2
str_2:
	mov  w, [istr]
	add  [pcl], w
	mkretlw  "Verde", 0x00

%define STR_NL 3
str_3:
	mov  w, [istr]
	add  [pcl], w
	mkretlw  0x0D, 0x0A, 0x00

; Seccion de configuracion
section config
	dw    _WDT_OFF & _XT_OSC
